﻿using SX.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SX.Data
{
    public class WhereBuilder4Mongo : WhereBuilder
    {
        StringBuilder builder = new StringBuilder();
        public override WhereBuilder LoadCondition(ConditionBase condition)
        {
            foreach (string key in condition.ConditionDic.Keys)
            {
                string value = condition[key];
                value = value.Replace("'", "\'").Replace("\"", "\\\""); // 防止注入 
                if (key.StartsWith("r_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string op = "$eq";
                    if (key.EndsWith("_fr"))
                    {
                        op = "$gte";
                        var dtFrom = CommonHelper.ToDateTime(value);
                        value = " ISODate(\"" + dtFrom.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + "\")";
                        length = key.Length - 5;
                     
                    }
                    else if (key.EndsWith("_to"))
                    {
                        op = "$lte";
                        var dtFrom = CommonHelper.ToDateTime(value+ " 23:59:59");
                        value = " ISODate(\"" + dtFrom.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + "\")"; 
                        length = key.Length - 5;
                    }
                    else if (value.IndexOf(",") > 0)
                    {
                        op = "$in";
                    }
                    else
                    {
                        value = "\"" + value + "\"";
                    }
                    string field = key.Substring(2, length);

                    this.And(field.Replace("-", "."), op, value);
                }
                else if (key.StartsWith("l_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string field = key.Substring(2, length);
                    string op = "$regex";
                    this.And(field.Replace("-", "."), op, "'" + value + "', '$options': 'i'");
                }

                else if (key.StartsWith("i_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string field = key.Substring(2, length);
                    string op = "$in";

                    //value = value.Replace(",", "','");
                    this.And(field.Replace("-", "."), op, value);
                }
                else if (key.StartsWith("ni_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 3;
                    string field = key.Substring(3, length);
                    string op = "$nin";

                    //value = value.Replace(",", "','");
                    this.And(field.Replace("-", "."), op, value);
                }
                //// 位运算 
                //else if (key.StartsWith("b_") && !string.IsNullOrEmpty(value))
                //{
                //    int length = key.Length - 2;
                //    string field = key.Substring(2, length);
                //    var valueList = value.Split(',').Select(d => CommonHelper.ToInt(d)).ToList();
                //    int bitV = 0;
                //    foreach (var i in valueList)
                //    {
                //        bitV = i | bitV;
                //    }
                //    this.AddFormat(" {0} & {1} ={1}", field.Replace("-", "."), bitV);
                //}
                //// 位运算 in
                //else if (key.StartsWith("bi_") && !string.IsNullOrEmpty(value))
                //{
                //    int length = key.Length - 3;
                //    string field = key.Substring(3, length);
                //    var valueList = value.Split(',').Select(d => CommonHelper.ToInt(d)).ToList();
                //    int bitV = 0;
                //    foreach (var i in valueList)
                //    {
                //        bitV = i | bitV;
                //    }
                //    this.AddFormat(" {0} & {1} > 0 ", field.Replace("-", "."), bitV);
                //}
            }

            return this;
        }

        public override WhereBuilder And(string field, string op, string value)
        {

            switch (op)
            {
                case "$in":
                    And("{\""+ field+ "\":{ $in:[" + value + "] }}");
                    break;
                case "$nin":
                    And("{\"" + field + "\":{ $nin:[" + value + "] }}");
                    break;
                default:
                    And("{\"" + field + "\":{ \""+ op + "\":" + value + " }}"); 
                    break;
            }
            return this;
        }

        public override WhereBuilder And(string where)
        {
            if (!string.IsNullOrEmpty(builder.ToString()))
            {
                builder.Append(",");
            }
            builder.Append(where);
            return this;
        }

        public override string ToString()
        {
            return builder.ToString();
        }
    }
}
